package hu.imind.phonecalc.server;


import hu.imind.phonecalc.client.ContactService;
import hu.imind.phonecalc.client.dto.Call;
import hu.imind.phonecalc.client.dto.Contact;
import hu.imind.phonecalc.client.dto.NotLoggedInException;

import hu.imind.phonecalc.entity.Bill;
import hu.imind.phonecalc.entity.PhoneCalcUser;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.data.extensions.Name;
import com.google.gdata.data.extensions.PhoneNumber;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

@SuppressWarnings("serial")
public class ContactServiceImpl extends RemoteServiceServlet implements ContactService {

    private String sessionToken;
    private ContactsService contactsService = new ContactsService("imind-phonecalc-v1.0");

    public List<Contact> getContacts() throws NotLoggedInException {
        checkLoggedIn();

        List<Contact> contactList = new ArrayList<Contact>();

        try{
            URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full?max-results=1000");
            //Map<String, String> tokenInfo = AuthSubUtil.getTokenInfo(sessionToken, null);
            contactsService.setAuthSubToken(sessionToken);
            ContactFeed resultFeed = null;
            resultFeed = contactsService.getFeed(feedUrl, ContactFeed.class);
            for (int i = 0; i < resultFeed.getEntries().size(); i++) {
                Contact contact = new Contact();
                ContactEntry entry = resultFeed.getEntries().get(i);
                if (entry.hasName()) {
                    Name name = entry.getName();
                    String  fullNameToDisplay = null;
                    if (name.hasFullName()) {
                        fullNameToDisplay = name.getFullName().getValue();
                        if (name.getFullName().hasYomi()) {
                            fullNameToDisplay += " (" + name.getFullName().getYomi() + ")";
                        }
                    } else {
                        fullNameToDisplay = "(no full name found)";
                    }
                    contact.setName(fullNameToDisplay);

                    ArrayList<PhoneNumber> phoneNumberList = (ArrayList<PhoneNumber>) entry.getPhoneNumbers();
                    int pCount = 1;
                    for (Iterator<PhoneNumber> iterator = phoneNumberList.iterator(); iterator
                    .hasNext();) {
                        PhoneNumber phoneNumber = iterator.next();
                        contact.setPhoneNumber("phone" + pCount, phoneNumber.getPhoneNumber());
                        pCount++;
                    }
                    contact.setType(null);

                    contactList.add(contact);
                }
            }
        }catch (Exception e) {
            System.err.println(e.getMessage());
            return null;
        }
        return contactList;
    }

    private void checkLoggedIn() throws NotLoggedInException {
        // cookie-ban van a tokenünk
        HttpServletRequest request = getThreadLocalRequest();
        Cookie[] cookies = request.getCookies();
        for (int i = 0; i < cookies.length; i++) {
            if (cookies[i].getName().equalsIgnoreCase("googleAuthToken")) {
                sessionToken = cookies[i].getValue();
                contactsService.setAuthSubToken(sessionToken);
                return;
            }
        }
        throw new NotLoggedInException();
    }


    @SuppressWarnings("unused")
    private User getUser() {
        UserService userService = UserServiceFactory.getUserService();
        return userService.getCurrentUser();
    }

    public boolean saveNumbers(String workNumbers, String privNumbers, List<Call> calls, String date)
            throws NotLoggedInException {
        HttpSession session = getThreadLocalRequest().getSession();
        String email = session.getAttribute("email").toString();

        PersistenceManager pm = PMF.get().getPersistenceManager();

        PhoneCalcUser user = new PhoneCalcUser();
        user = pm.getObjectById(PhoneCalcUser.class, email);
        
        if (user == null) {
            System.err.println("Nincs meg ilyen user, ujat hozunk letre.");
            user = new PhoneCalcUser();
        }
        
        user.setEmail(email);
        user.setWorkNumbers(new Text(workNumbers));
        user.setPrivNumbers(new Text(privNumbers));
        
        Bill bill = null;
        if (calls != null && calls.size() > 0) {
            bill = new Bill();
            bill.addCalls(calls);
            bill.setDate(date);
            bill.setKey(email);
            user.addBill(bill);
        }
        
        boolean res = false;
        try {
            pm.makePersistent(user);
            if (bill != null) {
                pm.makePersistent(bill);
            }
            res = true;
        } catch (Exception e) {
            System.err.println("ContactService.saveNumbers exception: " + e.getMessage());
        } finally {
            pm.close();
        }
        
        return res;
    }

    public List<Call> getBill(String date) throws NotLoggedInException {
        HttpSession session = getThreadLocalRequest().getSession();
        String email = session.getAttribute("email").toString();

        PersistenceManager pm = PMF.get().getPersistenceManager();

        Bill bill = pm.getObjectById(Bill.class, Bill.createKey(email, date));
        if (bill == null) {
            return null;
        }
        return bill.getCallList();
    }
}
